Version 0.2.0
SecPatchLab is a full-stack Ubuntu security monitoring and patch-validation sandbox with a FastAPI backend and a React (Vite + TypeScript) frontend. It inventories installed packages, matches them against Canonical Ubuntu OVAL (USN) feeds, and can validate patches in a Docker-based build/test sandbox.
- Ubuntu Security Monitor (non-root): Scans installed packages and compares against OVAL fixed versions (Ubuntu/WSL).
- Patch-Validation Sandbox (Docker): Builds and tests packages with optional patch application.
- FastAPI backend: REST endpoints for scans and validation runs.
- React frontend: Scan results, run status, logs, and artifacts.
- SARIF Export: GitHub Security-compatible SARIF report generation.
- SBOM Generation: Software Bill of Materials for validated packages.
- CLI & API: Both command-line and REST API interfaces.
- CVE Demonstration: Complete CVE workflow demonstration mode.
- OVAL feed mapping is centralized. If Canonical changes file naming, update the mapping in
secpatchlab/core/oval.py. - Validation requires Docker. The tool fails gracefully if Docker isn’t available.
Validation runs use a hardened docker run configuration by default:
- Drops Linux capabilities (
--cap-drop ALL) - Resource limits (
--memory 512m,--cpus 1.0,--pids-limit 128) - Filesystem restrictions (
--read-only,--tmpfs /tmp:rw,noexec,nosuid,size=100m) - Network isolation (
--network none) - Optional seccomp profile:
docker/seccomp-secpatchlab.json - Optional AppArmor (when available):
--security-opt apparmor=docker-default
If your Docker host doesn’t support one of these options, SecPatchLab falls back to a simpler docker run so the validation still executes, and the run log/summary reflects what happened.
OVAL feeds are downloaded and cached locally in ~/.cache/secpatchlab.
- Conditional requests via ETag (
If-None-Match) when available - Fallback mirrors (Canonical primary + secondary mirror)
- Basic content validation (must parse as OVAL XML)
- SHA256 hashing to detect feed changes/corruption and avoid unnecessary rewrites
Use --refresh to force a refresh.
Package vulnerability comparison uses Debian/Ubuntu version semantics (epochs, revisions, backports), not naive string comparison.
This project is safe to open source. It contains no hard‑coded secrets and uses public Ubuntu OVAL feeds by default. Keep local artifacts (runs/, .venv/, node_modules/) out of the repo, which is already handled by .gitignore.
- Node.js 18+ for the frontend
- Docker Desktop for validation runs
- Python 3.11+ for the backend/CLI
Notes:
- Real scans require
dpkg-queryand/etc/os-release(Ubuntu). On Windows, SecPatchLab runs those commands inside WSL. - If you don’t have WSL/Ubuntu available (or your host is fully patched), use
secpatchlab seed-demoto populate the UI with deterministic demo outputs.
Open this folder in VS Code.
Run these in PowerShell (recommended on Windows):
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -U pip
.\.venv\Scripts\python.exe -m pip install -e .If you are using Git Bash, don’t run PowerShell cmdlets directly. Instead, either switch your VS Code terminal to PowerShell, or run Python via the venv path:
./.venv/Scripts/python.exe -m pip install -U pip
./.venv/Scripts/python.exe -m pip install -e ..\.venv\Scripts\python.exe -m uvicorn backend.main:app --host 127.0.0.1 --port 8000If you’re using Git Bash:
./.venv/Scripts/python.exe -m uvicorn backend.main:app --host 127.0.0.1 --port 8000cd frontend
npm installNotes:
- The frontend is a Vite + React + TypeScript app.
- In dev mode, the frontend calls
/api/*and Vite proxies those requests to the FastAPI backend athttp://127.0.0.1:8000(seefrontend/vite.config.ts). - If you change backend ports/hosts, update the proxy or run the backend on
127.0.0.1:8000.
Useful npm commands:
npm install— install dependenciesnpm run dev -- --host— start the dev servernpm run build— production buildnpm run preview -- --host— preview the production build locally
npm run dev -- --hostQuick sanity check (recommended):
- Backend health: http://127.0.0.1:8000/api/health should return
{"status":"ok"} - Frontend loads: http://localhost:5173
If the UI shows POST http://127.0.0.1:5173/api/scan 500, the backend usually isn’t reachable on port 8000 (or it crashed). Start the backend (Step 3) and retry.
If your machine is fully patched (or you’re not on Ubuntu), you can still demo the UI by seeding a scan with findings plus validation runs.
secpatchlab seed-demoWindows notes:
- If
secpatchlabisn’t on your PATH yet, run./.venv/Scripts/secpatchlab.exe seed-demo(Git Bash) or.\.venv\Scripts\secpatchlab.exe seed-demo(PowerShell).
Open http://localhost:5173 and:
- In Scan, use Load previous scan and pick the
scan-demo-...entry (it has findings) - In Validation Runs, click
validate-demo-...-ok(success) andvalidate-demo-...-fail(failure)
docker compose up --buildTip (Windows): if you installed editable mode into a venv and secpatchlab isn’t on your PATH, call it via the venv binary:
- PowerShell:
.\.venv\Scripts\secpatchlab.exe <command> - Git Bash:
./.venv/Scripts/secpatchlab.exe <command>
Run a security vulnerability scan.
# Basic scan
secpatchlab scan
# Top 20 findings
secpatchlab scan --top 20
# Export to JSON
secpatchlab scan --format json --output results.json
# Export to SARIF (GitHub Security)
secpatchlab scan --format sarif --output results.sarif
# Refresh OVAL cache
secpatchlab scan --refreshRun package validation in sandbox.
# Basic validation
secpatchlab validate --package openssl
# With custom patch
secpatchlab validate --package openssl --patch ./patches/fix.patch
# With specific Ubuntu release
secpatchlab validate --package sudo --release jammy
# Generate SBOM report
secpatchlab validate --package openssl --sbomRun a complete CVE demonstration workflow.
# Demo with specific CVE
secpatchlab demo --cve CVE-2023-0464
# Generate reports
secpatchlab demo --cve CVE-2023-0464 --output-dir ./cve-reports
# Output formats
secpatchlab demo --cve CVE-2023-0464 --format sarif --output-dir ./reportsRun end-to-end scan and validation workflow.
# Scan and validate top 3 packages
secpatchlab run --top 3Seed demo data under runs/ (one scan with findings + one success run + one failure run) so the frontend can showcase both successful and failed validations.
secpatchlab seed-demomake scan— Run vulnerability scanmake api— Start FastAPI backend servermake ui— Start React frontend dev servermake dev— Run both backend and frontendmake validate PKG=openssl PATCH=./patches/fix.patch— Validate a package
OVAL_BASE_URL(default: https://security-metadata.canonical.com/oval/)SECPATCHLAB_WSL_DISTRO(Windows only): set to a specific WSL distro name (as shown bywsl -l -q) if you have multiple distros and want to pin which one SecPatchLab uses for scans.
GET /api/health— Check API status
POST /api/scan— Run a vulnerability scan (body:{"top": 20, "refresh": false})GET /api/scans— List all scan runsGET /api/scans/{scan_id}— Get scan results by ID
POST /api/validate— Start validation run (body:{"package": "openssl", "patch_path": null, "release": null})GET /api/runs— List all validation runsGET /api/runs/{run_id}— Get validation run detailsGET /api/runs/{run_id}/log— Get validation run logsGET /api/runs/{run_id}/artifacts— List validation artifactsGET /api/runs/{run_id}/download?path=...— Download a specific artifact (the/artifactsresponse includes prebuilt URLs)
Run the test suite with pytest:
# Install pytest if not already installed
pip install pytest
# Run all tests
pytest
# Run specific test file
pytest tests/test_dpkg.py
# Run with verbose output
pytest -vSee the docs/ directory for detailed documentation:
- correctness-evaluation.md — Validation methodology and correctness
- limitations.md — Known limitations and constraints
- threat-model.md — Security considerations and threat model
secpatchlab/— Core Python package and CLIbackend/— FastAPI appfrontend/— Vite + React UIdocker/— Validation Dockerfile template and configsruns/— Scan and validation outputstests/— Test suite (pytest)docs/— Additional documentation (limitations, threat model, correctness evaluation)
Upload SARIF reports to GitHub Code Scanning.
For most repos, the most reliable approach is GitHub Actions using github/codeql-action/upload-sarif.
If you upload from the CLI, be aware GitHub’s API requirements can vary (for example: authentication scopes and whether the SARIF must be compressed/encoded). Treat the snippet below as an advanced option and verify against current GitHub docs for your repo.
Example CLI flow:
# Generate SARIF report
secpatchlab scan --format sarif --output results.sarif
# Upload to GitHub (requires gh CLI)
gh api repos/OWNER/REPO/code-scanning/sarifs \
-F commit_sha=$(git rev-parse HEAD) \
-F ref=refs/heads/main \
-F sarif=@results.sarifOr use the demo command with GitHub upload:
secpatchlab demo --cve CVE-2023-0464 --output-dir ./reports
gh api repos/OWNER/REPO/code-scanning/sarifs -F sarif=@./reports/cve-2023-0464-results.sarif/etc/os-releasenot found: You’re running a real scan on Windows (SecPatchLab’s scanner expects an Ubuntu-like environment). Useseed-demoto showcase the UI on Windows, or run scans from Ubuntu/WSL/Docker.- Frontend shows
POST http://127.0.0.1:5173/api/scan 500: In dev mode, Vite proxies/api/*to the backend athttp://127.0.0.1:8000. Make sure the FastAPI server is running (Step 3) and thathttp://127.0.0.1:8000/api/healthreturns{"status":"ok"}. npm run dev -- --hostfails: Ensure the command has the space before--.secpatchlab: command not found: The package isn't installed. Runpip install -e .in the project root.- Docker validation fails: Ensure Docker Desktop is running.
- OVAL cache errors: Try running with
--refreshto force refresh the OVAL cache. - Test failures: Ensure you're in the correct Python environment and have installed test dependencies.
Check the docs/ directory for detailed information on limitations, threat model, and correctness evaluation.